#ifndef PG_DRIVER_HPP
#define PG_DRIVER_HPP

#include <sql/sql_driver.hpp>

struct DriverData;

class PostgresSQLDriver final : public ISqlDriver {
    DriverData *const d;
public:
    PostgresSQLDriver ();
    ~PostgresSQLDriver ();

    void                  InitConnection () override;
    bool                  IsConfigured () override;
    void                  InitTables () const override;
    [[nodiscard]] int32_t GetDataVersion () const override;
    void                  MigrateTables (int32_t old_version) const override;
    void                  InitPreparedStatements () const override;

    bool                         KeepAlive () override;
    std::vector<Tag>             AllTags () const override;
    Tag                          NewTag (const std::string &tag_name, uint32_t color, uint32_t level) const override;
    bool                         DeleteTag (int tag_id) const override;
    bool                         UpdateTag (Tag &tag) const override;
    std::vector<RedMineActivity> AllRedMineActivities () const override;
    bool                         DeleteRedMineActivity (int act_id) const override;
    bool                         UpdateRedMineActivity (RedMineActivity &tag) const override;
    std::vector<RedMineIssue>    AllRedMineIssues () const override;
    bool                         DeleteRedMineIssue (int issue_id) const override;
    bool                         UpdateRedMineIssue (RedMineIssue &tag) const override;
    WorkItem                     NewWorkItem (double             hour, const std::string &comment, const std::string &note,
                                              const std::string &create_date, int32_t priority) const override;
    bool                     SetWorkItemActivity (int work_id, int act_id) const override;
    bool                     SetWorkItemIssue (int work_id, int issue_id) const override;
    bool                     SetWorkItemUploaded (int work_id) const override;
    bool                     UpdateWorkItem (WorkItem &tag) const override;
    bool                     DeleteWorkItem (int work_id) const override;
    bool                     AddItemTag (int work_id, int tag_id) const override;
    bool                     DeleteItemTag (int work_id, int tag_id) const override;
    bool                     ClearItemTags (int work_id) const override;
    std::vector<Tag>         AllWorkItemTags (int work_id) override;
    std::vector<std::string> GetYearList () const override;
    std::vector<std::string> GetMonthList (const std::string &year) const override;
    std::vector<std::string> GetDayList (const std::string &year_and_month) const override;
    std::vector<WorkItem>    GetDailyItems (const std::string &date) const override;
    std::vector<WorkItem>
    GetItemsByTagAndDate (const std::string &date_start, const std::string &date_end, int tag_id_l1, int tag_id_l2) const override;
    StatisticsResult       GetStatisticsResult (const std::string &date_start, const std::string &date_end) const override;
    StatisticsResult       GetStatisticsResult () const override;
    StatisticsResult       GetStatisticsResult(const std::string &date_start, const std::string &date_end, int tag_id) const override;
    WorkTask               NewTask (std::string task_desc, const std::string &create_date, uint32_t color) override;
    bool                   UpdateTask (const WorkTask &task) override;
    bool                   DeleteTask (const WorkTask &task) override;
    bool                   SetTaskStatus (WorkTask &task, TaskStatus status) override;
    std::vector<WorkTask>  GetTasks () const override;
    WorkTask               GetCurrentTask () const override;
    void                   ClearActiveTask() const override;
    TimeEntry              NewTimeEntry (int32_t task_id, const std::string &start_date_time) override;
    bool                   UpdateTimeEntry (TimeEntry &entry, const std::string &end_time, int32_t duration) override;
    void                   MarkTimeEntryAsExported(TimeEntry &entry) const override;
    std::vector<TimeEntry> GetTimeEntries (int32_t task_id, const std::string &date_beg, const std::string &date_end) override;
    std::vector<TimeEntry> GetTimeEntries(const std::string &date_beg, const std::string &date_end) const override;
    TimeEntry              GetCurrentTimeEntry(int32_t entry_id) const override;
    
    CfgItemBase*           GetConfig() const override;
};

#endif // PG_DRIVER_HPP
